#include <iostream>
#include <random>
#include <cstring>
#include <dds/dds.h>
#include "start_atomic_0817_emergency_response_service.h" // IDL生成的C语言头文件
#include "../../../include/log_client/LogClient.h"

// DDS实体句柄
static dds_entity_t participant;
static dds_entity_t topic;
static dds_entity_t publisher;
static dds_entity_t writer;

// 清理DDS资源
static void cleanup()
{
    if (writer != DDS_HANDLE_NIL)
        dds_delete(writer);
    if (publisher != DDS_HANDLE_NIL)
        dds_delete(publisher);
    if (topic != DDS_HANDLE_NIL)
        dds_delete(topic);
    if (participant != DDS_HANDLE_NIL)
        dds_delete(participant);
}

// 生成随机应急事件输入数据
start_atomic_0817_emergency_response_service_EmergencyInput generate_random_emergency_data()
{
    // 静态随机数生成器（确保全局只初始化一次）
    static std::mt19937 rng(std::random_device{}());
    std::uniform_int_distribution<int> event_id_dist(1000, 9999);         // 事件ID范围
    std::uniform_int_distribution<int> severity_dist(1, 5);               // 严重级别(1-5)
    std::uniform_int_distribution<int> ip_segment_dist(0, 255);           // IP地址段(0-255)
    std::uniform_int_distribution<int> type_idx_dist(0, 2);               // 事件类型索引
    std::uniform_int_distribution<int> service_idx_dist(0, 1);            // 服务类型索引
    std::uniform_int_distribution<int> db_idx_dist(1, 3);                 // 数据库编号

    // 事件类型选项
    const char* event_types[] = {"fire", "flood", "earthquake"};
    // 服务类型选项
    const char* services[] = {"emergency_response", "medical_rescue"};

    // 初始化结构体
    start_atomic_0817_emergency_response_service_EmergencyInput data;
    
    // 生成事件ID
    int event_id = event_id_dist(rng);
    std::string event_id_str = "event_" + std::to_string(event_id);
    data.event_id = strdup(event_id_str.c_str());

    // 随机选择事件类型
    int type_idx = type_idx_dist(rng);
    data.event_type = strdup(event_types[type_idx]);

    // 生成严重级别
    data.severity_level = severity_dist(rng);

    // 生成随机IP地址 (xxx.xxx.xxx.xxx)
    int ip_seg1 = ip_segment_dist(rng);
    int ip_seg2 = ip_segment_dist(rng);
    int ip_seg3 = ip_segment_dist(rng);
    int ip_seg4 = ip_segment_dist(rng);
    std::string ip_str = std::to_string(ip_seg1) + "." + 
                         std::to_string(ip_seg2) + "." + 
                         std::to_string(ip_seg3) + "." + 
                         std::to_string(ip_seg4);
    data.ip = strdup(ip_str.c_str());

    // 随机选择服务类型
    int service_idx = service_idx_dist(rng);
    data.service = strdup(services[service_idx]);

    // 生成数据库名称
    std::string db_str = "emergency_db_" + std::to_string(db_idx_dist(rng));
    data.database = strdup(db_str.c_str());

    return data;
}

// 释放应急事件数据中的字符串内存
static void free_emergency_data(start_atomic_0817_emergency_response_service_EmergencyInput& data)
{
    if (data.event_id)
    {
        free(data.event_id);
        data.event_id = nullptr;
    }
    if (data.event_type)
    {
        free(data.event_type);
        data.event_type = nullptr;
    }
    if (data.ip)
    {
        free(data.ip);
        data.ip = nullptr;
    }
    if (data.service)
    {
        free(data.service);
        data.service = nullptr;
    }
    if (data.database)
    {
        free(data.database);
        data.database = nullptr;
    }
}

int main()
{
    // 初始化日志
    LogClient::getInstance().init("mock_atomic_0817_emergency_response_service","mock_atomic_0817_emergency_response_service");

    dds_return_t rc;

    // 1. 初始化DDS参与者（DomainParticipant）
    participant = dds_create_participant(DDS_DOMAIN_DEFAULT, NULL, NULL);
    if (participant < 0)
    {
        std::cerr << "错误：创建参与者失败，原因：" << dds_strretcode(-participant) << std::endl;
        LogClient::getInstance().logError("创建参与者失败，原因：" + std::string(dds_strretcode(-participant)));
        cleanup();
        return EXIT_FAILURE;
    }

    // 2. 创建主题（Topic），名称需与订阅者一致
    topic = dds_create_topic(
        participant,
        &start_atomic_0817_emergency_response_service_EmergencyInput_desc, // IDL生成的类型描述
        "start_atomic_0817_emergency_response_service",                      // 主题名称（必须与订阅者一致）
        NULL, NULL);
    if (topic < 0)
    {
        std::cerr << "错误：创建主题失败，原因：" << dds_strretcode(-topic) << std::endl;
        LogClient::getInstance().logError("创建主题失败，原因：" + std::string(dds_strretcode(-topic)));
        cleanup();
        return EXIT_FAILURE;
    }

    // 3. 创建发布者（Publisher）
    publisher = dds_create_publisher(participant, NULL, NULL);
    if (publisher < 0)
    {
        std::cerr << "错误：创建发布者失败，原因：" << dds_strretcode(-publisher) << std::endl;
        LogClient::getInstance().logError("创建发布者失败，原因：" + std::string(dds_strretcode(-publisher)));
        cleanup();
        return EXIT_FAILURE;
    }

    dds_qos_t *qos = dds_create_qos();
    dds_qset_reliability(qos, DDS_RELIABILITY_RELIABLE, DDS_SECS(10));
    dds_qset_history(qos, DDS_HISTORY_KEEP_LAST, 10);

    // 4. 创建数据写入器（DataWriter）
    writer = dds_create_writer(publisher, topic, qos, NULL);
    if (writer < 0)
    {
        std::cerr << "错误：创建写入器失败，原因：" << dds_strretcode(-writer) << std::endl;
        LogClient::getInstance().logError("创建写入器失败，原因：" + std::string(dds_strretcode(-writer)));
        cleanup();
        return EXIT_FAILURE;
    }
    dds_delete_qos(qos);

    std::cout << "DDS应急响应服务数据发布者已启动，开始发送数据..." << std::endl;
    LogClient::getInstance().logInfo("DDS应急响应服务数据发布者已启动，开始发送数据...");

    // 5. 循环发送数据（持续发送，每次间隔1秒）
    int i = 0;
    while (1)
    {
        // 生成随机应急事件数据
        start_atomic_0817_emergency_response_service_EmergencyInput data = generate_random_emergency_data();

        // 发送数据
        rc = dds_write(writer, &data);
        if (rc != DDS_RETCODE_OK)
        {
            std::cerr << "错误：dds_write失败，原因：" << dds_strretcode(-rc) << std::endl;
            LogClient::getInstance().logError("dds_write失败，原因：" + std::string(dds_strretcode(-rc)));
            free_emergency_data(data);
            cleanup();
            return EXIT_FAILURE;
        }

        // 打印发送的信息
        std::string info = "已发送应急事件数据（第" + std::to_string(i + 1) + "次）：\n";
        info += "  事件ID：" + std::string(data.event_id) + "\n";
        info += "  事件类型：" + std::string(data.event_type) + "\n";
        info += "  严重级别：" + std::to_string(data.severity_level) + "\n";
        info += "  IP地址：" + std::string(data.ip) + "\n";
        info += "  服务类型：" + std::string(data.service) + "\n";
        info += "  数据库：" + std::string(data.database);

        std::cout << "==============================" << std::endl;
        std::cout << info << std::endl;
        std::cout << "==============================" << std::endl;
        LogClient::getInstance().logInfo(info);

        // 释放当前数据的字符串内存
        free_emergency_data(data);

        // 间隔1秒发送
        i++;
        dds_sleepfor(DDS_SECS(1));
    }

    // 清理资源
    cleanup();
    return EXIT_SUCCESS;
}